package com.ddd.listener;

import com.ddd.core.constants.ProfileConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.boot.autoconfigure.web.ServerProperties;
import org.springframework.boot.context.event.ApplicationReadyEvent;
import org.springframework.context.ApplicationListener;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.core.env.Profiles;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;

import java.text.MessageFormat;

/**
 * @description:
 * @author: zhongwenbin
 * @date: 2024-10-23 11:00
 **/
@Slf4j
@Component
public class StartupOutputListener implements ApplicationListener<ApplicationReadyEvent > {
    private static final String[] SWAGGER_ENVIRONMENT_CLASSES = {
            "springfox.documentation.spring.web.plugins.Docket"};

    private boolean deduceSwaggerEnvironment() {
        for (String className : SWAGGER_ENVIRONMENT_CLASSES) {
            // 判断指定的类名是否存在
            if (!ClassUtils.isPresent(className, null)) {
                return false;
            }
        }
        return true;
    }


    private boolean isNativeEnvironment(Environment environment) {
        return environment.acceptsProfiles(Profiles.of(ProfileConstants.NATIVE));
    }

    @Override
    public void onApplicationEvent(ApplicationReadyEvent event) {
        ConfigurableApplicationContext applicationContext = event.getApplicationContext();
        // 多个容器启动时，只输出一次
        if (applicationContext.getParent() != null){
            return;
        }
        Environment environment = applicationContext.getEnvironment();
        if (isNativeEnvironment(environment)) {
            ServerProperties serverProperties = applicationContext
                    .getBean(ServerProperties.class);
            // 端口
            Integer port = serverProperties.getPort();
            if (port == -1) {
                port = 8080;
            }
            // 上下文
            String contextPath = serverProperties.getServlet().getContextPath();
            if (StringUtils.isBlank(contextPath)) {
                contextPath = "/";
            }
            String docBaseUrl = MessageFormat
                    .format("http://localhost:{0}{1}{2}", String.valueOf(port), contextPath,
                            StringUtils.endsWith(contextPath, "/") ? "" : "/");
            log.info("\n----------------------------------------------------------\n\t" +
                            "Application '{}' is running! Access URLs:\n\t" +
                            "Local: \t\thttp://localhost:{}{}\n\t" +
                            "{}" +
                            "{}" +
                            "Profile: \t\t{}\n\t" +
                            "Profile(s): \t{}\n----------------------------------------------------------",
                    environment.getProperty("spring.application.name"),
                    port,
                    contextPath,
                    deduceSwaggerEnvironment() ?
                            "Knife4j: \t\t" + docBaseUrl + "doc.html\n\t"
                            : "",
                    deduceSwaggerEnvironment() ?
                            "Swagger: \t\t" + docBaseUrl + "swagger-ui.html\n\t"
                            : "",
                    environment.getProperty("spring.profiles.active"),
                    environment.getActiveProfiles());
        }
    }
}
